#include "thirdparty/gtest/gtest.h"
#include "common/reflect/reflect_class.h"
using namespace common;
using namespace std;
class A {
 public:
  virtual std::string Say() = 0;
  virtual ~A() {}
};

class B: public A, public DynamicCreator<A, B> {
 public:
  B() {}
  virtual std::string Say() {
    std::cout << "B Say" << std::endl;
    return "B";
  }
};

class C: public A, public DynamicCreator<A, C, int> {
 public:
  C(int x) {
    x_ = x;
  }
  virtual std::string Say() {
    return "C(" + std::to_string(x_) + ")";
  }
 private:
  int x_;
};

class ComputerFactory {
 public:
  template<typename ...Args>
  static A* CreateComputerA(const std::string& str_type_name, Args... args) {
    A* p = ClassFactory<A, Args...>::Instance()->Create(
        str_type_name, std::forward<Args>(args)...);
    return p;
  }
};


TEST(reflect, reflect) {
 A* a2 = ComputerFactory::CreateComputerA("B");
 A* a3 = ComputerFactory::CreateComputerA("C", 3);
 A* a4 = ComputerFactory::CreateComputerA("C", 4);
 EXPECT_EQ("B", a2->Say());
 EXPECT_EQ("C(3)", a3->Say());
 EXPECT_EQ("C(4)", a4->Say());
}

